from skimage.io import imread
import pyclesperanto_prototype as cle
import stackview
import napari
from skimage.measure import regionprops_table
import pandas as pd
import numpy as np
import napari_pyclesperanto_assistant._advanced_statistics as nas
from napari_clusters_plotter._dimensionality_reduction import umap
from napari_clusters_plotter._clustering import kmeans_clustering
import seaborn as sns
import matplotlib.pyplot as plt
nuclei = imread("c:/structure/data/Lund-100MB.tif")[2]

stackview.insight(nuclei)
shape(116, 636, 354)
dtypeuint8
size24.9 MB
min0
max233
viewer = napari.Viewer(ndisplay=3)
viewer.add_image(nuclei)
napari.utils.nbscreenshot(viewer, canvas_only=True)
viewer.camera.angles
(0.0, 0.0, 90.00000000000001)
viewer.camera.angles = (90, 0, 90)
viewer.camera.zoom = 2.6
napari.utils.nbscreenshot(viewer, canvas_only=True)
bg_subtracted = cle.top_hat_box(nuclei, radius_x=10, radius_y=10, radius_z=10)
labels = cle.voronoi_otsu_labeling(bg_subtracted, spot_sigma=0.5, outline_sigma=0)

viewer.add_labels(labels)
napari.utils.nbscreenshot(viewer, canvas_only=True)
neighbor_connections = cle.draw_mesh_between_proximal_labels(labels, maximum_distance=25)

viewer.add_image(neighbor_connections, opacity=0.5)
napari.utils.nbscreenshot(viewer, canvas_only=True)
neighbor_stats = cle.statistics_of_labelled_neighbors(labels, proximal_distances=[25], nearest_neighbor_ns=[], dilation_radii=[])
neighbor_stats
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\pyclesperanto_prototype\_tier0\_opencl_execute.py:281: RuntimeWarning: overflow encountered in cast
  arguments.append(np.array([value], np.float32))
{'label': array([   1,    2,    3, ..., 2184, 2185, 2186]),
 'touching_neighbor_count': array([5., 3., 5., ..., 0., 0., 0.], dtype=float32),
 'minimum_distance_of_touching_neighbors': array([6.2099104, 4.783322 , 5.3679237, ..., 0.       , 0.       ,
        0.       ], dtype=float32),
 'average_distance_of_touching_neighbors': array([9.229854 , 5.9108377, 8.382152 , ..., 0.       , 0.       ,
        0.       ], dtype=float32),
 'maximum_distance_of_touching_neighbors': array([12.065423 ,  6.8475013, 10.020198 , ...,  0.       ,  0.       ,
         0.       ], dtype=float32),
 'max_min_distance_ratio_of_touching_neighbors': array([1.9429303, 1.4315368, 1.8666804, ...,       nan,       nan,
              nan], dtype=float32),
 'proximal_neighbor_count_d25': array([25., 18., 16., ...,  1.,  2.,  2.], dtype=float32),
 'distance_to_most_distant_other': array([427.15463, 445.42847, 466.85413, ..., 378.41937, 389.53204,
        366.03748], dtype=float32),
 'touch_portion_above_0_neighbor_count': array([5., 3., 5., ..., 0., 0., 0.], dtype=float32),
 'touch_portion_above_0.16_neighbor_count': array([1., 2., 1., ..., 0., 0., 0.], dtype=float32),
 'touch_portion_above_0.2_neighbor_count': array([1., 2., 1., ..., 0., 0., 0.], dtype=float32),
 'touch_portion_above_0.33_neighbor_count': array([0., 0., 0., ..., 0., 0., 0.], dtype=float32),
 'touch_portion_above_0.5_neighbor_count': array([0., 0., 0., ..., 0., 0., 0.], dtype=float32),
 'touch_portion_above_0.75_neighbor_count': array([0., 0., 0., ..., 0., 0., 0.], dtype=float32),
 'touch_count_sum': array([122.,  95., 227., ...,   0.,   0.,   0.], dtype=float32),
 'minimum_touch_count': array([  2.,  17.,  18., ..., 291., 291., 291.], dtype=float32),
 'maximum_touch_count': array([51., 44., 99., ...,  0.,  0.,  0.], dtype=float32),
 'minimum_touch_portion': array([0.00809717, 0.11486486, 0.03964758, ..., 0.4084507 , 0.4084507 ,
        0.4084507 ], dtype=float32),
 'maximum_touch_portion': array([0.20647773, 0.2972973 , 0.21806167, ..., 0.        , 0.        ,
        0.        ], dtype=float32),
 'standard_deviation_touch_portion': array([0.12640575, 0.0777027 , 0.12824279, ..., 0.        , 0.        ,
        0.        ], dtype=float32)}
intensity_stats = cle.statistics_of_labelled_pixels(nuclei, labels)
intensity_stats
{'label': array([   1,    2,    3, ..., 2184, 2185, 2186]),
 'original_label': array([   1,    2,    3, ..., 2184, 2185, 2186]),
 'bbox_min_x': array([ 24.,  24.,  24., ..., 337., 340., 342.], dtype=float32),
 'bbox_min_y': array([399., 421., 447., ..., 364., 295., 333.], dtype=float32),
 'bbox_min_z': array([0., 0., 0., ..., 0., 0., 0.], dtype=float32),
 'bbox_max_x': array([ 33.,  32.,  33., ..., 341., 344., 344.], dtype=float32),
 'bbox_max_y': array([407., 427., 455., ..., 371., 303., 337.], dtype=float32),
 'bbox_max_z': array([ 5.,  3., 10., ...,  4.,  6.,  1.], dtype=float32),
 'bbox_width': array([10.,  9., 10., ...,  5.,  5.,  3.], dtype=float32),
 'bbox_height': array([9., 7., 9., ..., 8., 9., 5.], dtype=float32),
 'bbox_depth': array([ 6.,  4., 11., ...,  5.,  7.,  2.], dtype=float32),
 'min_intensity': array([72., 76., 71., ..., 42., 41., 41.], dtype=float32),
 'max_intensity': array([118., 123., 118., ...,  56.,  63.,  46.], dtype=float32),
 'sum_intensity': array([23517., 10137., 36104., ...,  5469.,  9536.,   730.], dtype=float32),
 'area': array([241., 101., 405., ..., 115., 195.,  17.], dtype=float32),
 'mean_intensity': array([ 97.58091 , 100.36633 ,  89.145676, ...,  47.556522,  48.902565,
         42.941177], dtype=float32),
 'sum_intensity_times_x': array([ 683280.,  280863., 1032066., ..., 1854783., 3261392.,  250256.],
       dtype=float32),
 'mass_center_x': array([ 29.054726,  27.706718,  28.585918, ..., 339.1448  , 342.0084  ,
        342.81644 ], dtype=float32),
 'sum_intensity_times_y': array([ 9481387.,  4303452., 16278259., ...,  2011203.,  2853611.,
          244765.], dtype=float32),
 'mass_center_y': array([403.17163, 424.52914, 450.87134, ..., 367.74603, 299.24612,
        335.29453], dtype=float32),
 'sum_intensity_times_z': array([ 36878.,  10033., 175518., ...,   7696.,  22396.,    207.],
       dtype=float32),
 'mass_center_z': array([1.5681422 , 0.98974055, 4.861456  , ..., 1.4072043 , 2.348574  ,
        0.28356165], dtype=float32),
 'sum_x': array([ 6971.,  2773., 11571., ..., 39002., 66691.,  5828.], dtype=float32),
 'centroid_x': array([ 28.925312,  27.455446,  28.57037 , ..., 339.14783 , 342.00513 ,
        342.82352 ], dtype=float32),
 'sum_y': array([ 97158.,  42871., 182621., ...,  42289.,  58356.,   5700.],
       dtype=float32),
 'centroid_y': array([403.14523, 424.46533, 450.91605, ..., 367.73044, 299.26154,
        335.29413], dtype=float32),
 'sum_z': array([ 383.,  102., 1963., ...,  167.,  469.,    5.], dtype=float32),
 'centroid_z': array([1.5892116 , 1.009901  , 4.846914  , ..., 1.452174  , 2.4051282 ,
        0.29411766], dtype=float32),
 'sum_distance_to_centroid': array([ 764.4512  ,  253.58925 , 1471.8877  , ...,  281.93085 ,
         553.607   ,   23.183668], dtype=float32),
 'mean_distance_to_centroid': array([3.1719966, 2.5107846, 3.6342907, ..., 2.4515727, 2.8390102,
        1.3637452], dtype=float32),
 'sum_distance_to_mass_center': array([ 764.4398  ,  254.87625 , 1471.9258  , ...,  281.9798  ,
         553.65326 ,   23.185287], dtype=float32),
 'mean_distance_to_mass_center': array([3.1719494, 2.5235271, 3.6343846, ..., 2.4519982, 2.8392475,
        1.3638405], dtype=float32),
 'standard_deviation_intensity': array([10.205904 , 14.266017 , 11.750536 , ...,  4.137193 ,  5.784661 ,
         1.7977302], dtype=float32),
 'max_distance_to_centroid': array([6.6307807, 4.9968524, 7.272151 , ..., 4.09282  , 4.557525 ,
        2.3196287], dtype=float32),
 'max_distance_to_mass_center': array([6.7388296, 5.2128887, 7.273856 , ..., 4.091985 , 4.5413914,
        2.319256 ], dtype=float32),
 'mean_max_distance_to_centroid_ratio': array([2.0904124, 1.9901557, 2.0009823, ..., 1.6694672, 1.6053219,
        1.7009252], dtype=float32),
 'mean_max_distance_to_mass_center_ratio': array([2.1245072, 2.0657153, 2.0013998, ..., 1.668837 , 1.5995053,
        1.7005333], dtype=float32)}
table = nas.advanced_statistics(nuclei, labels)
table
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\napari_pyclesperanto_assistant\_advanced_statistics.py:18: UserWarning: 'Statistics of labeled pixels including neighborhood statistics' is deprecated. Use 'Label statistics' instead.
  warnings.warn("'Statistics of labeled pixels including neighborhood statistics' is deprecated. Use 'Label statistics' instead.")
Measurements Completed.
label original_label bbox_min_x bbox_min_y bbox_min_z bbox_max_x bbox_max_y bbox_max_z bbox_width bbox_height ... mean_distance_to_mass_center standard_deviation_intensity max_distance_to_centroid max_distance_to_mass_center mean_max_distance_to_centroid_ratio mean_max_distance_to_mass_center_ratio avg_distance_of_2_nearest_neigbors avg_distance_of_3_nearest_neigbors avg_distance_of_4_nearest_neigbors touching_neighbor_count
0 1 1 24.0 399.0 0.0 33.0 407.0 5.0 10.0 9.0 ... 3.171949 10.205904 6.630781 6.738830 2.090412 2.124507 7.590932 8.087852 8.520962 5.0
1 2 2 24.0 421.0 0.0 32.0 427.0 3.0 9.0 7.0 ... 2.523527 14.266017 4.996852 5.212889 1.990156 2.065715 5.442506 5.910838 6.655530 3.0
2 3 3 24.0 447.0 0.0 33.0 455.0 10.0 10.0 9.0 ... 3.634385 11.750536 7.272151 7.273856 2.000982 2.001400 6.675785 7.331525 7.972640 5.0
3 4 4 24.0 454.0 0.0 34.0 463.0 4.0 11.0 10.0 ... 3.281820 9.279823 5.899060 5.854911 1.798308 1.784044 7.276857 8.062333 8.871074 4.0
4 5 5 26.0 474.0 0.0 33.0 482.0 6.0 8.0 9.0 ... 3.012358 9.451112 5.345889 5.261563 1.776183 1.746659 8.528680 8.941842 10.448359 3.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2181 2182 2182 336.0 314.0 9.0 341.0 322.0 18.0 6.0 9.0 ... 3.302892 5.972755 5.170120 5.152297 1.565350 1.559935 20.661205 21.193321 22.736378 0.0
2182 2183 2183 337.0 246.0 0.0 341.0 254.0 6.0 5.0 9.0 ... 2.875455 5.113707 4.701997 4.726860 1.635346 1.643865 24.059181 24.953699 27.809708 0.0
2183 2184 2184 337.0 364.0 0.0 341.0 371.0 4.0 5.0 8.0 ... 2.451998 4.137193 4.092820 4.091985 1.669467 1.668837 22.216997 24.679289 26.675577 0.0
2184 2185 2185 340.0 295.0 0.0 344.0 303.0 6.0 5.0 9.0 ... 2.839247 5.784661 4.557525 4.541391 1.605322 1.599505 20.784912 23.756897 25.889828 0.0
2185 2186 2186 342.0 333.0 0.0 344.0 337.0 1.0 3.0 5.0 ... 1.363840 1.797730 2.319629 2.319256 1.700925 1.700533 20.612461 24.629789 27.179501 0.0

2186 rows × 41 columns

table.columns
Index(['label', 'original_label', 'bbox_min_x', 'bbox_min_y', 'bbox_min_z',
       'bbox_max_x', 'bbox_max_y', 'bbox_max_z', 'bbox_width', 'bbox_height',
       'bbox_depth', 'min_intensity', 'max_intensity', 'sum_intensity', 'area',
       'mean_intensity', 'sum_intensity_times_x', 'mass_center_x',
       'sum_intensity_times_y', 'mass_center_y', 'sum_intensity_times_z',
       'mass_center_z', 'sum_x', 'centroid_x', 'sum_y', 'centroid_y', 'sum_z',
       'centroid_z', 'sum_distance_to_centroid', 'mean_distance_to_centroid',
       'sum_distance_to_mass_center', 'mean_distance_to_mass_center',
       'standard_deviation_intensity', 'max_distance_to_centroid',
       'max_distance_to_mass_center', 'mean_max_distance_to_centroid_ratio',
       'mean_max_distance_to_mass_center_ratio',
       'avg_distance_of_2_nearest_neigbors',
       'avg_distance_of_3_nearest_neigbors',
       'avg_distance_of_4_nearest_neigbors', 'touching_neighbor_count'],
      dtype='object')
table_dim_red = pd.DataFrame({k: table[k] for k in [

#'min_intensity', 
#'max_intensity', 
#'area',
'mean_intensity', 
#'mass_center_x',
#'mass_center_y', 
#'mass_center_z', 
#'centroid_x', 
#'centroid_y', 
#'centroid_z', 
#'mean_distance_to_centroid',
#'mean_distance_to_mass_center',
'standard_deviation_intensity', 
#'max_distance_to_centroid',
#'max_distance_to_mass_center', 
#'mean_max_distance_to_centroid_ratio',
#'mean_max_distance_to_mass_center_ratio',
#'avg_distance_of_2_nearest_neigbors',
#'avg_distance_of_3_nearest_neigbors',
'avg_distance_of_4_nearest_neigbors', 
'touching_neighbor_count'

]})

umap_table = umap(table_dim_red, n_neighbors=15, n_components=2, min_dist=0.1)
umap_table
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\umap\distances.py:1063: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.
  @numba.jit()
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\umap\distances.py:1071: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.
  @numba.jit()
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\umap\distances.py:1086: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.
  @numba.jit()
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\umap\umap_.py:660: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.
  @numba.jit()
('UMAP',
 array([[ 7.2152653 ,  0.25958052],
        [ 7.1479826 ,  0.49318957],
        [ 4.948551  ,  0.11478776],
        ...,
        [-4.4583693 ,  6.3534966 ],
        [-4.556163  ,  6.0747447 ],
        [-4.2785654 ,  6.71291   ]], dtype=float32))
umap_table[1][:,1].shape
(2186,)
table_to_cluster = pd.DataFrame({
    "UMAP0":umap_table[1][:,0],
    "UMAP1":umap_table[1][:,0],    
})

clustering = kmeans_clustering(table_to_cluster, cluster_number=3, iterations=10)
clustering
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\sklearn\cluster\_kmeans.py:1382: UserWarning: KMeans is known to have a memory leak on Windows with MKL, when there are less chunks than available threads. You can avoid it by setting the environment variable OMP_NUM_THREADS=9.
  warnings.warn(
('KMEANS', array([2, 2, 2, ..., 0, 0, 0]))
table['kmeans_clustering'] = clustering[1]
table['UMAP0'] = umap_table[1][:,0]
table['UMAP1'] = umap_table[1][:,1]
import matplotlib.pyplot as plt
plt.style.use('dark_background')
from napari_clusters_plotter._utilities import get_nice_colormap
# Create a scatter plot of UMAP0 vs UMAP1 colored by kmeans_clustering
sns.scatterplot(data=table, x='UMAP0', y='UMAP1', hue='kmeans_clustering', palette=get_nice_colormap())
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\seaborn\_oldcore.py:1498: FutureWarning: is_categorical_dtype is deprecated and will be removed in a future version. Use isinstance(dtype, CategoricalDtype) instead
  if pd.api.types.is_categorical_dtype(vector):
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\seaborn\_oldcore.py:1498: FutureWarning: is_categorical_dtype is deprecated and will be removed in a future version. Use isinstance(dtype, CategoricalDtype) instead
  if pd.api.types.is_categorical_dtype(vector):
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\seaborn\_oldcore.py:1498: FutureWarning: is_categorical_dtype is deprecated and will be removed in a future version. Use isinstance(dtype, CategoricalDtype) instead
  if pd.api.types.is_categorical_dtype(vector):
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\seaborn\_oldcore.py:1498: FutureWarning: is_categorical_dtype is deprecated and will be removed in a future version. Use isinstance(dtype, CategoricalDtype) instead
  if pd.api.types.is_categorical_dtype(vector):
C:\Users\haase\AppData\Local\Temp\ipykernel_19652\1629480065.py:2: UserWarning: The palette list has more values (255) than needed (3), which may not be intended.
  sns.scatterplot(data=table, x='UMAP0', y='UMAP1', hue='kmeans_clustering', palette=get_nice_colormap())
<Axes: xlabel='UMAP0', ylabel='UMAP1'>
../_images/6b781de09aa4359301ab0e0bb6095335c3de60dae8b35bef76c81d6769edc5f4.png
table.columns
Index(['label', 'original_label', 'bbox_min_x', 'bbox_min_y', 'bbox_min_z',
       'bbox_max_x', 'bbox_max_y', 'bbox_max_z', 'bbox_width', 'bbox_height',
       'bbox_depth', 'min_intensity', 'max_intensity', 'sum_intensity', 'area',
       'mean_intensity', 'sum_intensity_times_x', 'mass_center_x',
       'sum_intensity_times_y', 'mass_center_y', 'sum_intensity_times_z',
       'mass_center_z', 'sum_x', 'centroid_x', 'sum_y', 'centroid_y', 'sum_z',
       'centroid_z', 'sum_distance_to_centroid', 'mean_distance_to_centroid',
       'sum_distance_to_mass_center', 'mean_distance_to_mass_center',
       'standard_deviation_intensity', 'max_distance_to_centroid',
       'max_distance_to_mass_center', 'mean_max_distance_to_centroid_ratio',
       'mean_max_distance_to_mass_center_ratio',
       'avg_distance_of_2_nearest_neigbors',
       'avg_distance_of_3_nearest_neigbors',
       'avg_distance_of_4_nearest_neigbors', 'touching_neighbor_count',
       'kmeans_clustering', 'UMAP0', 'UMAP1'],
      dtype='object')
plt.figure(figsize=(10, 6))
sns.scatterplot(data=table, x='centroid_y', y='centroid_x', hue='kmeans_clustering', palette=get_nice_colormap())
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\seaborn\_oldcore.py:1498: FutureWarning: is_categorical_dtype is deprecated and will be removed in a future version. Use isinstance(dtype, CategoricalDtype) instead
  if pd.api.types.is_categorical_dtype(vector):
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\seaborn\_oldcore.py:1498: FutureWarning: is_categorical_dtype is deprecated and will be removed in a future version. Use isinstance(dtype, CategoricalDtype) instead
  if pd.api.types.is_categorical_dtype(vector):
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\seaborn\_oldcore.py:1498: FutureWarning: is_categorical_dtype is deprecated and will be removed in a future version. Use isinstance(dtype, CategoricalDtype) instead
  if pd.api.types.is_categorical_dtype(vector):
C:\Users\haase\mambaforge\envs\bio39\lib\site-packages\seaborn\_oldcore.py:1498: FutureWarning: is_categorical_dtype is deprecated and will be removed in a future version. Use isinstance(dtype, CategoricalDtype) instead
  if pd.api.types.is_categorical_dtype(vector):
C:\Users\haase\AppData\Local\Temp\ipykernel_19652\153530680.py:2: UserWarning: The palette list has more values (255) than needed (3), which may not be intended.
  sns.scatterplot(data=table, x='centroid_y', y='centroid_x', hue='kmeans_clustering', palette=get_nice_colormap())
<Axes: xlabel='centroid_y', ylabel='centroid_x'>
../_images/0cadd59df694ec902bdfbd5a8b7b31a8e08dbabc7ab161f2b864d2202ae2aab6.png
trainers = [
    "Stéphane Rigaud, Image Analysis Hub, Institut Pasteur, Paris",
    "Laura Žigutytė, Clinical AI / Kather lab, EKFZ, TU Dresden",
    "Anja Neumann, ScaDS.AI, Uni Leipzig",
    "Marie-Sophie von Braun, ScaDS.AI, Uni Leipzig",
    "Matthias Täschner, ScaDS.AI, Uni Leipzig",
    "Christian Martin, ScaDS.AI, Uni Leipzig",
    "Jan Ewald, ScaDS.AI, Uni Leipzig",
    "Robert Haase, ScaDS.AI, Uni Leipzig",
]
sorted(trainers)
['Anja Neumann, ScaDS.AI, Uni Leipzig',
 'Christian Martin, ScaDS.AI, Uni Leipzig',
 'Jan Ewald, ScaDS.AI, Uni Leipzig',
 'Laura Žigutytė, Clinical AI / Kather lab, EKFZ, TU Dresden',
 'Marie-Sophie von Braun, ScaDS.AI, Uni Leipzig',
 'Matthias Täschner, ScaDS.AI, Uni Leipzig',
 'Robert Haase, ScaDS.AI, Uni Leipzig',
 'Stéphane Rigaud, Image Analysis Hub, Institut Pasteur, Paris']